package com.example.fireassistant_server.service.impl;

import com.example.fireassistant_server.dto.hydrant.FireHydrantAddRequest;
import com.example.fireassistant_server.dto.hydrant.FireHydrantDto;
import com.example.fireassistant_server.dto.PointSearchFilter;
import com.example.fireassistant_server.dto.hydrant.FireHydrantUpdateRequest;
import com.example.fireassistant_server.entity.File;
import com.example.fireassistant_server.entity.FireHydrant;
import com.example.fireassistant_server.entity.User;
import com.example.fireassistant_server.exception.BizException;
import com.example.fireassistant_server.exception.ExceptionType;
import com.example.fireassistant_server.mapper.FireHydrantMapper;
import com.example.fireassistant_server.repository.FireHydrantRepository;
import com.example.fireassistant_server.repository.HydrantFilesRepository;
import com.example.fireassistant_server.repository.spec.*;
import com.example.fireassistant_server.service.FileService;
import com.example.fireassistant_server.service.FireHydrantService;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Service
public class FireHydrantServiceImpl implements FireHydrantService {

    private FireHydrantRepository fireHydrantRepository;

    private FireHydrantMapper fireHydrantMapper;

    private FileService fileService;

    // 网页端、客户端插入消火栓
    // 微信端添加消火栓
    @Override
    public FireHydrantDto addHydrant(FireHydrantAddRequest hydrantAddRequest, User user) {
        FireHydrant fireHydrant = fireHydrantMapper.createEntity(hydrantAddRequest);
        //核对是否存在同一位置消火栓
        checkHydrant(fireHydrant.getLatitude(),fireHydrant.getLongitude());
        fireHydrant.setUser(user);
        return fireHydrantMapper.toDto(fireHydrantRepository.save(fireHydrant));
    }

    @Override
    public Page<FireHydrantDto> search(PointSearchFilter pointSearchFilter) {
        PointSpecification specs = new PointSpecification();
        //添加所查询的latitude范围
        if (!Objects.equals(pointSearchFilter.getMinLatitude(), null) && !Objects.equals(pointSearchFilter.getMaxLatitude(), null)) {
            specs.add(new PointSearchCriteria("latitude", pointSearchFilter.getMinLatitude(), pointSearchFilter.getMaxLatitude(), SearchOperation.BETWEEN));
        }
        //添加所查询的longitude范围
        if (!Objects.equals(pointSearchFilter.getMinLongitude(), null) && !Objects.equals(pointSearchFilter.getMaxLongitude(), null)){
            specs.add(new PointSearchCriteria("longitude", pointSearchFilter.getMinLongitude(), pointSearchFilter.getMaxLongitude(), SearchOperation.BETWEEN));
        }

        return fireHydrantRepository.findAll(specs, pointSearchFilter.toPageable()).map(fireHydrantMapper::toDto);
    }

    @Override
    public FireHydrant get(String id) {
        Optional<FireHydrant> fireHydrant = fireHydrantRepository.findById(id);
        if (!fireHydrant.isPresent()) {
            throw new BizException(ExceptionType.HYDRANT_NOT_FOUND);
        }
        return fireHydrant.get();
    }

    //更新消火栓信息
    //不赋值的为null TODO 更新其它的
    @Override
    public FireHydrantDto update(String id, FireHydrantUpdateRequest fireHydrantUpdateRequest) {
        Optional<FireHydrant> fireHydrant = fireHydrantRepository.findById(id);
        if (!fireHydrant.isPresent()) {
            throw new BizException(ExceptionType.HYDRANT_NOT_FOUND);
        }

        if (fireHydrantUpdateRequest.getLatitude()!= null){
            fireHydrant.get().setLatitude(fireHydrantUpdateRequest.getLatitude());
        }
        if (fireHydrantUpdateRequest.getLongitude()!= null){
            fireHydrant.get().setLongitude(fireHydrantUpdateRequest.getLongitude());
        }
        if (fireHydrantUpdateRequest.getFlowRate()!= null){
            fireHydrant.get().setFlowRate(fireHydrantUpdateRequest.getFlowRate());
        }

        if (fireHydrantUpdateRequest.getName()!= null){
            fireHydrant.get().setName(fireHydrantUpdateRequest.getName());
        }

        if (fireHydrantUpdateRequest.getStatus()!= null){
            fireHydrant.get().setStatus(fireHydrantUpdateRequest.getStatus());
        }
        if (fireHydrantUpdateRequest.getScore()!= null){
            fireHydrant.get().setScore(fireHydrantUpdateRequest.getScore());
        }

        if (fireHydrantUpdateRequest.getDescription()!= null){
            fireHydrant.get().setDescription(fireHydrantUpdateRequest.getDescription());
        }

        return fireHydrantMapper.toDto(fireHydrantRepository.save(fireHydrant.get()));

    }


    @Override
    public void delete(String id) {
        Optional<FireHydrant> fireHydrant = fireHydrantRepository.findById(id);
        if (!fireHydrant.isPresent()) {
            throw new BizException(ExceptionType.HYDRANT_NOT_FOUND);
        }
        //删除消火栓，需要先删除对应的file
        List<File> fileArrayList = fireHydrant.get().getFiles();
        if (!fileArrayList.isEmpty()){
            fileArrayList.forEach(file -> {
                System.out.println(file.getId());
                fileService.delete("hydrant",file.getId());
            });
        }
        // 删除消火栓
        fireHydrantRepository.deleteById(id);
    }

    public void checkHydrant(BigDecimal latitude,BigDecimal longitude){
        HydrantSpecification specs = new HydrantSpecification();
        //添加所查询的latitude范围
        specs.add(new SearchCriteria("latitude", latitude, SearchOperation.EQUAL));
        //添加所查询的longitude范围
        specs.add(new SearchCriteria("longitude", longitude, SearchOperation.EQUAL));
        List<FireHydrant> fireHydrant = fireHydrantRepository.findAll(specs);
        if (!fireHydrant.isEmpty()){
            throw new BizException(ExceptionType.HYDRANT_DUPLICATE);
        }
    }
    @Autowired
    public void setFireHydrantRepository(FireHydrantRepository fireHydrantRepository) {
        this.fireHydrantRepository = fireHydrantRepository;
    }

    @Autowired
    public void setFireHydrantMapper(FireHydrantMapper fireHydrantMapper) {
        this.fireHydrantMapper = fireHydrantMapper;
    }

    @Autowired
    public void setFileService(FileService fileService) {
        this.fileService = fileService;
    }
}
